<?php
class Front_Model_UserMapper {
	protected $_dbTable;

	public function __construct() {

	}

	public function setDbTable($dbTable)
	{
		if (is_string($dbTable)) {
			$dbTable = new $dbTable();
		}
		if (!$dbTable instanceof Zend_Db_Table_Abstract) {
			throw new Exception('Invalid table data gateway provided');
		}
		$this->_dbTable = $dbTable;
		return $this;
	}

	public function getDbTable()
	{
		if (null === $this->_dbTable) {
			$this->setDbTable('Front_Model_DbTable_User');
		}
		return $this->_dbTable;
	}

	public function verifyLogin($username, $password, Front_Model_User $userLoginSucess) {
		$authen = Zend_Auth::getInstance ();
		$db = Zend_Db_Table::getDefaultAdapter();

		$authAdapter = new Front_Model_DbTable_AuthUser($db);
		$authAdapter->setIdentity($username);
		$authAdapter->setCredential($password);
		$result = $authen->authenticate($authAdapter);
		if (!$result->isValid()) {
			return;
		} else {
			// get all info about this user from the login table
			// ommit only the password, we don't need that
			$userInfo = (object)$authAdapter->getResultRowObject(null, 'password');
			$userArrayInfo = $this->objectToArray($userInfo);
			$this->populateUserFromArray($userArrayInfo, $userLoginSucess);
			// the default storage is a session with namespace Zend_Auth
			$authStorage = $authen->getStorage();
			if ($userArrayInfo['role'] == 1) {
				$userInfo->roleStr = 'admin';
			} else if ($userArrayInfo['role'] == 2) {
				$userInfo->roleStr = 'user';
			}

			$authStorage->write($userInfo);
			return $userLoginSucess;
		}
	}

	public function populateUserFromArray($array, Front_Model_User $userModel) {
		$userModel->_uid = $array['uid'];
		$userModel->_address = $array['address'];
		$userModel->_username = $array['username'];
		$userModel->_phone = $array['phone'];
		$userModel->_email = $array['email'];
		$userModel->_remain = $array['remain'];
		$userModel->_role = $array['role'];
		$userModel->_fullname = $array['fullname'];

	}

	public static function objectToArray($d) {
		if (is_object($d)) {
			// Gets the properties of the given object
			// with get_object_vars function
			$d = get_object_vars($d);
		}

		if (is_array($d)) {
			/*
			 * Return array converted to object
			 * Using __FUNCTION__ (Magic constant)
			 * for recursive call
			 */
			return $d;
		}
		else {
			// Return array
			return $d;
		}
	}

	public function save(Front_Model_User $userInfo)
	{
		$uid = $userInfo->_uid;

		$data = array(
            'fullname'   => $userInfo->_fullname,
            'username' => $userInfo->_username,
            'password' => $userInfo->_password,
			'address' => $userInfo->_address,
			'phone' => $userInfo->_phone,
			'email' => $userInfo->_email,
			'role' => $userInfo->_role,
			'remain' => $userInfo->_remain
		);

		if (!isset($uid)) {
			unset($data['uid']);
			$this->getDbTable()->insert($data);
		} else {
			$this->getDbTable()->update($data, array('uid = ?' => $uid));
		}
	}

	public function populateAccountFromRow(Zend_Db_Table_Row_Abstract $row, Front_Model_User $userModel) {
		$userModel->_uid = $row->uid;
		$userModel->_fullname = $row->fullname;
		$userModel->_username = $row->username;
		$userModel->_password = $row->password;
		$userModel->_address = $row->address;
		$userModel->_phone = $row->phone;
		$userModel->_email = $row->email;
		$userModel->_role = $row->role;
		$userModel->_remain=$row->remain;
	}

	public function find($uid, Front_Model_User $userinfo)
	{
		$result = $this->getDbTable()->find($uid);
		if (0 == count($result)) {
			return;
		}
		$row = $result->current();
		$this->populateAccountFromRow($row, $userinfo);
		return $row;
	}

	public function fetchAll()
	{
		$resultSet = $this->getDbTable()->fetchAll();
		$entries   = array();
		foreach ($resultSet as $row) {
			$entry = new Front_Model_User();
			$this->populateAccountFromRow($row, $entry);
			$entries[] = $entry;
		}
		return $entries;
	}

	public function findUserByRole($role) {
		$resultSet = $this->getDbTable()->fetchAll(array('role = ?' => $role));
		if (0 == count($resultSet)) {
			return;
		}
		$entries = array();
		foreach ($resultSet as $row) {
			$entry = new Front_Model_User();
			$this->populateAccountFromRow($row, $entry);
			$entries[] = $entry;
		}
		return $entries;
	}

	public function delete($uid)
	{
		$result = $this->getDbTable()->find($uid);
		if (0 == count($result)) {
			return;
		}
		return $this->getDbTable()->delete(array('uid = ?' => $uid));
	}

	public function isValidUsername($username) {
		$resultSet = $this->getDbTable()->fetchAll(array('username = ?' => $username));
		if (0 == count($resultSet)) {
			return true;
		}
		return false;
	}
	
	public function vaidateRemain($uid, $quantity) {
		$userinfo = new Front_Model_User();
		$has = $this->find($uid, $userinfo);
		if (isset($has)) {
			if ($userinfo->_remain - $quantity >= 0) {
				return true;
			}
		}
		return false;
	}
}